/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.MrpMps;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import merlion.common.util.Consts;
import merlion.mrp.ppm.pojo.WeeklyMPSTemp;
import merlion.mrp.ppm.session.MPSPlanningSessionLocal;

/**
 *
 * @author Zhang Ying
 */
@ManagedBean
@ViewScoped
public class WeeklyMpsManagerBean {

    public static final String WMPS = "WMPS";
    @EJB
    private MPSPlanningSessionLocal mspSession;
    // for seleciton list
    private Integer selectedYear;
    private String selectedMonth;
    private List<Integer> yearList;
    private List<String> monthList;
    private ArrayList<Integer> counterForProduct;
    private ArrayList<Integer> counterForWeek;
    private WeeklyMPSTemp selectedWMPS;

    /** Creates a new instance of MpsManagerBean */
    public WeeklyMpsManagerBean() {
        counterForProduct = new ArrayList<Integer>();
        for (int i = 0; i < 4; i++) {
            counterForProduct.add(i);
        }
        counterForWeek = new ArrayList<Integer>();
        for (int i = 0; i < 5; i++) {
            counterForWeek.add(i);
        }
    }

    // for selection page
    public String redirectToViewWeeklyDetail() {
        int month = getMonthIndex(selectedMonth);
        if (!mspSession.checkWeeklyMPSAvailable(month, selectedYear)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful",
                    "Sorry, this period of weekly master production schedule is not available yet. Please select another period."));
            return null;
        }
        int totalWkingDays = mspSession.getTotalWorkingDaysForMonth(month, selectedYear);
        ArrayList<ArrayList<Long>> weeklyDemand = mspSession.getEachWeekDemandForOneMonth(month, selectedYear);
//        for (int i = 0 ; i < 4; i++){
//            for (int j = 0; j < 5; j++){
//                System.out.println("testing for demand haha: "+ weeklyDemand.get(i).get(j));
//            }
//        }
        ArrayList<Long> monthlyDemand = mspSession.getMonthlyDemand(month, selectedYear);
        ArrayList<Integer> workingDaysList = mspSession.getWorkingDaysList(month, selectedYear);
        ArrayList<ArrayList<Timestamp>> startEndDays = mspSession.getStartEndDaysList(month, selectedYear);

        WeeklyMPSTemp wmpsTemp = new WeeklyMPSTemp(selectedYear, month, totalWkingDays);
        wmpsTemp.setWeeklyDemand(weeklyDemand);
        wmpsTemp.setMonthlyDemand(monthlyDemand);
        wmpsTemp.setStartEndDays(startEndDays);
        wmpsTemp.setWorkingDays(workingDaysList);

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(WMPS);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(WMPS, wmpsTemp);

        return getRedirectPath(Consts.VIEW_WEEKLY_MPS_PATH + "Detail");
    }

    public List<String> getMonthList() {
        if (monthList == null) {
            monthList = new ArrayList<String>();
            for (int i = 1; i <= 12; i++) {
                monthList.add(getMonthEnglish(i));
            }
        }
        return monthList;
    }

    public void setMonthList(List<String> monthList) {
        this.monthList = monthList;
    }

    public List<Integer> getYearList() {
        if (yearList == null) {
            Calendar calendar = Calendar.getInstance();
            Date date = calendar.getTime();
            int currentYear = Integer.valueOf(Consts.sdfYear.format(date));
            yearList = new ArrayList<Integer>();
            for (int i = currentYear; i < (currentYear + 5); i++) {
                yearList.add(i);
            }
        }
        return yearList;
    }

    public void setYearList(List<Integer> yearList) {
        this.yearList = yearList;
    }

    public String getSelectedMonth() {
        return selectedMonth;
    }

    public void setSelectedMonth(String selectedMonth) {
        this.selectedMonth = selectedMonth;
    }

    public Integer getSelectedYear() {
        return selectedYear;
    }

    public void setSelectedYear(Integer selectedYear) {
        this.selectedYear = selectedYear;
    }

    // for view detail page
    public ArrayList<Integer> getCounterForProduct() {
        return counterForProduct;
    }

    public void setCounterForProduct(ArrayList<Integer> counterForProduct) {
        this.counterForProduct = counterForProduct;
    }

    public ArrayList<Integer> getCounterForWeek() {
        return counterForWeek;
    }

    public void setCounterForWeek(ArrayList<Integer> counterForWeek) {
        this.counterForWeek = counterForWeek;
    }

    public WeeklyMPSTemp getSelectedWMPS() {
        if (selectedWMPS == null) {
            WeeklyMPSTemp temp = (WeeklyMPSTemp) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(WMPS);
            if (temp != null) {
                selectedWMPS = temp;
            }
        }
        return selectedWMPS;
    }

    public void setSelectedWMPS(WeeklyMPSTemp selectedWMPS) {
        this.selectedWMPS = selectedWMPS;
    }

    public Double returnWeeklyDemandInHours(Long weeklyDemand, int productCounter) {
        if (productCounter == 0) {
            return 1.0 * weeklyDemand / Consts.CASES_PER_HOUR_CLASSIC;
        } else if (productCounter == 1) {
            return 1.0 * weeklyDemand / Consts.CASES_PER_HOUR_CLASSIC;
        } else if (productCounter == 2) {
            return 1.0 * weeklyDemand / Consts.CASES_PER_HOUR_PREMIUM;
        } else if (productCounter == 3) {
            return 1.0 * weeklyDemand / Consts.CASES_PER_HOUR_PREMIUM;
        } else {
            return 0.0;
        }
    }

    public Double returnUtilizationNormalShift(Integer weekCount) {
        Integer totalDaysPW = getSelectedWMPS().getWorkingDays().get(weekCount) * 16;
        double sumOfHrs = Long.valueOf(0);
        for (int i = 0; i < 4; i++) {
            if (i == 0 || i ==1){
                sumOfHrs += 1.0 *selectedWMPS.getWeeklyDemand().get(i).get(weekCount) / Consts.CASES_PER_HOUR_CLASSIC;
            }else {
                sumOfHrs += 1.0 *selectedWMPS.getWeeklyDemand().get(i).get(weekCount) / Consts.CASES_PER_HOUR_PREMIUM;
            }
        }
        if (totalDaysPW == 0){
            return null;
        }
        return 1.0 * sumOfHrs / totalDaysPW;
    }

    public Double returnUtilizationOvertimeShift(Integer weekCount) {
        Integer totalDaysPW = getSelectedWMPS().getWorkingDays().get(weekCount) * 24;
        double sumOfHrs = Long.valueOf(0);
        for (int i = 0; i < 4; i++) {
            if (i == 0 || i ==1){
                sumOfHrs += 1.0 *selectedWMPS.getWeeklyDemand().get(i).get(weekCount) / Consts.CASES_PER_HOUR_CLASSIC;
            }else {
                sumOfHrs += 1.0 *selectedWMPS.getWeeklyDemand().get(i).get(weekCount) / Consts.CASES_PER_HOUR_PREMIUM;
            }
        }
        if (totalDaysPW == 0){
            return null;
        }
        return 1.0 * sumOfHrs / totalDaysPW;
    }
    
    public boolean renderCell(Integer workingDays){
        if (workingDays > 0 ){
            return true;
        }else {
            return false;
        }
    }
    
    public boolean renderCellAccWorkingDays(Integer weekCount){
        if (getSelectedWMPS().getWorkingDays().get(weekCount) > 0) {
            return true;
        } else {
            return false;
        }
    }

    // for general purpose
    private Long roundToLong(Double d) {
        return Math.round(d);
    }

    private String getRedirectPath(String path) {
        return path + "?faces-redirect=true";
    }

    private String getMonthEnglish(int i) {
        switch (i) {
            case 1:
                return Consts.JAN;
            case 2:
                return Consts.FEB;
            case 3:
                return Consts.MAR;
            case 4:
                return Consts.APR;
            case 5:
                return Consts.MAY;
            case 6:
                return Consts.JUN;
            case 7:
                return Consts.JUL;
            case 8:
                return Consts.AUG;
            case 9:
                return Consts.SEP;
            case 10:
                return Consts.OCT;
            case 11:
                return Consts.NOV;
            case 12:
                return Consts.DEC;
            default:
                return "";
        }
    }

    private int getMonthIndex(String label) {
        if (label.equals(Consts.JAN)) {
            return 1;
        } else if (label.equals(Consts.FEB)) {
            return 2;
        } else if (label.equals(Consts.MAR)) {
            return 3;
        } else if (label.equals(Consts.APR)) {
            return 4;
        } else if (label.equals(Consts.MAY)) {
            return 5;
        } else if (label.equals(Consts.JUN)) {
            return 6;
        } else if (label.equals(Consts.JUL)) {
            return 7;
        } else if (label.equals(Consts.AUG)) {
            return 8;
        } else if (label.equals(Consts.SEP)) {
            return 9;
        } else if (label.equals(Consts.OCT)) {
            return 10;
        } else if (label.equals(Consts.NOV)) {
            return 11;
        } else if (label.equals(Consts.DEC)) {
            return 12;
        } else {
            return 0;
        }
    }

    public String returnProductAlpha(Integer i) {
        if (i.intValue() == 0) {
            //return Consts.ProductType.BAR_A.getText();
            return "A";
        } else if (i.intValue() == 1) {
            //return Consts.ProductType.BAR_B.getText();
            return "B";
        } else if (i.intValue() == 2) {
            //return Consts.ProductType.BAR_C.getText();
            return "C";
        } else if (i.intValue() == 3) {
            //return Consts.ProductType.BAR_D.getText();
            return "D";
        } else {
            return "";
        }
    }
    
    public String returnProductName(Integer i) {
        if (i.intValue() == 0) {
            return Consts.ProductType.BAR_A.getText();
        } else if (i.intValue() == 1) {
            return Consts.ProductType.BAR_B.getText();
        } else if (i.intValue() == 2) {
            return Consts.ProductType.BAR_C.getText();
        } else if (i.intValue() == 3) {
            return Consts.ProductType.BAR_D.getText();
        } else {
            return "";
        }
    }

    public String returnFormattedDay(Timestamp t) {
        if (t == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
        return sdf.format(t);
    }
}
